/*******************************************************************************
 * Copyright (c) baifeiq.
 * 
 * @date            @author         @brief
 * 2021-07-12       baifeiq         First version: Define structure of task.
 * 2021-12-30       baifeiq         Reorganize the coding style.
 * 2022-01-11       baifeiq         Define new data types: struct os_sys_para.
 */

#ifndef OS_DEFINE_H__
#define OS_DEFINE_H__

#include "os_config.h"

#if defined (ARMCM4)
  #include "ARMCM4.h"
#elif defined (ARMCM4_FP)
  #include "ARMCM4_FP.h"
#else
  #error device not specified!
#endif

#ifndef OS_NULL
#define OS_NULL              (void *)(0x0)
#endif

#define OS_NULL_CHECK(x)     if(OS_NULL == x){return -1;}

#define OS_MEM32(addr)       *(volatile unsigned long *)(addr)
#define OS_MEM8(addr)        *(volatile unsigned char *)(addr)

/* Fixed size types. These are all optional. */
typedef signed char          os_int8_t;
typedef unsigned char        os_uint8_t;

typedef signed short         os_int16_t;
typedef unsigned short       os_uint16_t;

typedef signed int           os_int32_t;
typedef unsigned int         os_uint32_t;

typedef signed long long     os_int64_t;
typedef unsigned long long   os_uint64_t;

#define os_inline            static inline

/**
 * Working state of system tasks
 */
typedef enum
{
    OS_NOT_EXIST,           /**< Task does not exist or not initialized. */
	OS_RUNNING,             /**< Task is running. */
	OS_WAITE_DELAY,         /**< Task is waiting for delay. */
	OS_READY,               /**< Task is ready. */
    OS_SUSPENSION           /**< Task suspended. */
}os_task_status_t;

/**
 * Double List structure
 */
struct os_list_node
{
    struct os_list_node *prev;              /**< Point to prev node. */
    struct os_list_node *next;              /**< Point to next node. */
};
typedef struct os_list_node os_list_t;      /**< Type for double lists. */

/**
 * Single List structure
 */
struct os_slist_node
{
    struct os_slist_node *next;             /**< point to next node. */
};
typedef struct os_list_node os_slist_t;     /**< Type for single lists. */

/**
 * Event type
 */
typedef enum
{
    OS_EVENT_UNKNOWN = 0       /**< Event type is unknown. */
}os_event_type_t;

/**
 * Event structure
 */
typedef struct 
{
    os_event_type_t  type;      /**< Event type. */
    os_list_t        list;      /**< Event list. */
}os_event_t;

/**
 * Structure of system tasks
 */
struct os_task
{
	os_uint32_t		*stack_addr;            /**< Stack address. */
	os_uint8_t		pro;                    /**< Priority. */
	os_task_status_t	state;              /**< state of task. */
	os_uint32_t		timer;                  /**< Timer of task. */
	os_list_t	    list_delay;             /**< List of task. */
    os_list_t       list_event;             /**< List of tasks waiting for events.*/
    void            *param;                 /**< The param of task_remove_call. */
    void            (*task_remove_call)(void *param); /**< Call funtion when remove
                                                           the task. */
    os_event_t      *event;                 /**<  The event that the task is waiting 
                                                  for. */
    void            *event_msg;             /**<  Storage location of messages waiting 
                                                  for events. */
    os_uint32_t     event_result;           /**<  Result of event waiting. */
};
typedef struct os_task os_task_t;           /**< Type for system tasks. */

/**
 * Structure of os system parameter
 */
struct os_sys_para
{
    char const  *os_version;                /**< Version of os. */
    os_uint32_t os_time;                    /**< Time of os. */
    os_uint32_t ready_table;                /**< Task ready table. */
    os_uint8_t  scheduler_lock;             /**< Task lock counters. */
    os_task_t   *task_last;                 /**< Last task of os system. */
    os_task_t   *task_next;                 /**< Next task of os system. */
    os_task_t   *task_current;              /**< Current task of os system. */
    os_task_t   *task_table[OS_TASK_MAX + 1]; /**< OS_TASK_MAX is user's task num. */
    os_list_t   task_delay;                  /**< Task waiting delay list. */
    os_list_t   task_event;                  /**< List of tasks waiting for events.*/
};
typedef struct os_sys_para os_sys_para_t;   /**< Type for os system parameter. */

/**
 * @brief Set bit of value.
 * 
 * @param n Set target bit, n < 32.
 * @param value 
 */
os_inline void os_bit_set(os_uint8_t n, os_uint32_t *value)
{
	*value |= (0x01 << n);
}

/**
 * @brief Reset bit of value.
 * 
 * @param n Reset target bit, n < 32.
 * @param value 
 */
os_inline void os_bit_reset(os_uint8_t n, os_uint32_t *value)
{
	*value &= ~(0x01 << n);
}

/**
 * @brief Enter the critical interval
 */
os_inline os_uint32_t os_critical_enter(void)
{
    os_uint32_t os_interrupt = __get_PRIMASK ();

    //CMSIS.5.8.0
    __disable_irq();

    return os_interrupt;
}

/**
 * @brief Exit critical interval 
 */
os_inline void os_critical_quit(os_uint32_t os_interrupt)
{
    //CMSIS.5.8.0
    __set_PRIMASK (os_interrupt);
}

#endif /* OS_DEFINE_H__ */

